package com.hmdp.ThreadUtil.pc;

/**
 *@Author:fengxiaohui
 *@Description: 线程之间的通信问题：生产者和消费者问题
 *线程交替执行 A,B 交替打印0，1
 */
public class Task1 {
    public static void main(String[] args) {
        Date date = new Date();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    date.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    date.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    date.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    date.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D").start();

    }
}

//资源类
//JUC口诀：1、线程 操作 资源类
//2、判断、干活、通知
/**
* @Description:JUC口诀
1、线程 操作 资源类
2、判断、干活、通知
3、防止虚假唤醒，wait方法要注意
API Note:
推荐的等待方法是检查while循环中正在等待的条件，调用wait ，如下例所示。 除此之外，这种方法避免了可能由虚假唤醒引起的问题。
synchronized (obj) { while (<condition does not hold> and <timeout not exceeded>) { long timeoutMillis = ... ;
// recompute timeout values int nanos = ... ; obj.wait(timeoutMillis, nanos); } ... // Perform action appropriate to condition or timeout }
4、注意flag标志位，可能是volatile的
*/
class Date{
    private int number = 0;

    public synchronized  void increment() throws InterruptedException {
        //判断
        //防止虚假唤醒，wait方法要注意
        while (number != 0) {
            this.wait();

        }
        number++;
        System.out.println(Thread.currentThread().getName()+"=>" + number);
        //通知其他线程，我+1完毕了
        this.notifyAll();
    }

    public synchronized void decrement() throws InterruptedException {
        while (number == 0) {
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"=>" + number);
        //通知其他线程，我-1完毕了
        this.notifyAll();
    }
}